package com.ny.until;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Base64;
import java.util.Date;
import java.util.concurrent.TimeUnit;



@Component
public class JwtUtil {

    // 从配置文件读取密钥，避免硬编码和动态生成
    @Value("${jwt.secret:defaultSecretKeyForDevelopmentOnly1234567890}")
    private String secretKey;

    // 从配置文件读取过期时间，单位小时
    @Value("${jwt.expiration:10}")
    private long tokenExpiration;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 获取签名密钥
    private SecretKey getSecretKey() {
        // 如果密钥长度不足，进行处理
        byte[] keyBytes = secretKey.getBytes();
        if (keyBytes.length < 32) {
            byte[] newKey = new byte[32];
            System.arraycopy(keyBytes, 0, newKey, 0, keyBytes.length);
            keyBytes = newKey;
        }
        return Keys.hmacShaKeyFor(keyBytes);
    }

    // 根据用户名生成Token
    public String generateToken(String username) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + 1000 * 60 * 60 * tokenExpiration);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(getSecretKey(), SignatureAlgorithm.HS256)
                .compact();
    }

    // 验证Token有效性（签名+过期时间）
    public Boolean validateToken(String token) {
        try {
            Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())
                    .build()
                    .parseClaimsJws(token);
            return !isTokenExpired(token);
        } catch (Exception e) {
            return false;
        }
    }

    // 检查Token是否过期
    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    // 从Token中提取用户名
    public String getUsernameFromToken(String token) {
        return getClaims(token).getSubject();
    }

    // 从Token中提取过期时间
    public Date getExpirationDateFromToken(String token) {
        return getClaims(token).getExpiration();
    }

    // 解析Token获取Claims（负载信息）
    private Claims getClaims(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSecretKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    // 将Token存储到Redis（键：username:token，值：Token）
    public void storeToken(String token, String username) {
        redisTemplate.opsForValue().set("username:" + username, token, tokenExpiration, TimeUnit.HOURS);
    }

    // 从Redis中移除Token
    public void removeToken(String username) {
        redisTemplate.delete("username:" + username);
    }

    // 验证Redis中的Token是否匹配
    public boolean validateTokenInRedis(String token, String username) {
        String redisToken = (String) redisTemplate.opsForValue().get("username:" + username);
        return token.equals(redisToken) && validateToken(token);
    }

    // 从Redis获取用户的Token
    public String getTokenFromRedis(String username) {
        return (String) redisTemplate.opsForValue().get("username:" + username);
    }
}
